﻿using System;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;

namespace Nirvana
{
    [AddComponentMenu("Nirvana/UI/Bind/UI Variable Table")]
    public sealed class UIVariableTable : MonoBehaviour
    {
        [SerializeField]
        private UIVariable[] variables;
        private Dictionary<string, UIVariable> variableMap;
        public UIVariable[] Variables { get { return variables; } }

        private Dictionary<string,UIVariable> GetVariableData()
        {
            if(this.variableMap == null)
            {
                this.variableMap = new Dictionary<string, UIVariable>();
                if(this.variables != null)
                {
                    foreach(var p in this.variables)
                    {
                        this.variableMap.Add(p.VariableName, p);
                    }
                }
            }

            return this.variableMap;
        }

        public UIVariable FindVariable(string name)
        {
            UIVariable result;
            if(this.GetVariableData().TryGetValue(name,out result))
            {
                return result;
            }
            return null;
        }

        public string[] GetVariableNames()
        {
            string[] names = new string[this.variables.Length];
            for(int i = 0; i < this.variables.Length; i++)
            {
                names[i] = this.variables[i].VariableName;
            }
            return names;
        }

        public void Sort()
        {
            Array.Sort<UIVariable>(this.variables,(a,b)=> { return a.VariableName.CompareTo(b.VariableName); });
        }


        public void InitializeBinds()
        {
            Binds(this.transform);
        }

        public UIVariable GetVariable(int index)
        {
            return this.variables[index];
        }

        private void Binds(Transform trans)
        {
            UIVariableBind[] binds = trans.GetComponentsInChildren<UIVariableBind>(true);
            foreach(var p in binds)
            {
                p.Binds();
            }
        }

        void Awake()
        {
            Binds(this.transform);
        }

#if UNITY_EDITOR
        void OnValidate()
        {
            variableMap = null;
            if (this.variables != null)
            {
                foreach (var p in this.variables)
                {
                    p.Init();
                    p.ClearNoBinds();
                    p.OnHandleValueChanged();
                }
            }
        }


        public void InitDefaultVariable()
        {
            UIVariable variable = new UIVariable();
            if (this.variables == null)
            {
                this.variables = new UIVariable[1];
                this.variables[0] = variable;
            }
            else
            {
                ArrayUtility.Add<UIVariable>(ref this.variables, variable);
            }
        }
#endif
    }
}

